package com.acme.bankapp.service.bank;

import com.acme.bankapp.domain.bank.Bank;
import com.acme.bankapp.domain.bank.CheckingAccount;
import com.acme.bankapp.domain.bank.Client;
import com.acme.bankapp.domain.bank.SavingAccount;
import com.acme.bankapp.domain.bank.exceptions.ClientExistsException;
import com.acme.bankapp.domain.bank.exceptions.NotEnoughFundsException;
import com.acme.bankapp.service.bank.server.BankServer;

import java.io.IOException;

import static com.acme.bankapp.service.bank.BankService.*;
import static com.acme.bankapp.service.bank.ClientFactory.createClient;

public class BankApplication {
    public static final String DEFAULT_BANK_FILE_PATH = ".\\test3.txt";

    public static void main(String[] args) {
        Bank bank = null;
        boolean startBankAfter = false;
        for (int i = 0; i < args.length; i++) {
            switch (args[i]) {
                case "-loadfeed":
                    bank = doLoadfeed(args, i);
                    i++;
                    break;
                case "-loadbank":
                    bank = doLoadbank(args, i);
                    i++;
                    break;
                case "-server":
                    startBankAfter = true;
                    break;
            }
        }

        if (startBankAfter) {
            if (bank == null) {
                bank = defaultBank();
            }
            BankService.enableEmailToBank(bank);

            doStartServer(bank);
            BankService.stopBank(bank);
        }
    }

    private static void doStartServer(Bank bank) {
        System.out.println("Option server");
        BankServer bankServer = new BankServer();
        bankServer.startServer(bank, 2004);
    }

    private static Bank doLoadbank(String[] args, int i) {
        System.out.println("Option loading bank");
        paramsChecking(i, args.length, 1);
        try {
            Bank[] banks = BankService.readBanks(args[i + 1]);
            if (banks.length > 0) {
                return banks[0];
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static Bank doLoadfeed(String[] args, int i) {
        Bank bank = new Bank();

        System.out.println("Option loading feed");
        try {
            paramsChecking(i, args.length, 1);
            loadClients(bank, args[1]);
            return bank;
        } catch (IOException | ClientExistsException e) {
            e.printStackTrace();
            return null;
        }
    }

    private static void paramsChecking(int currentIndex, int maxIndex, int count) {
        if (currentIndex + count >= maxIndex) {
            throw new IllegalArgumentException("Args count not right");
        }
    }

    private static Bank defaultBank() {
        Bank bank = new Bank();

        try {
            addClient(bank, new Client(new CheckingAccount(100, 100), Client.Gender.MALE, "Ivanov A.A.", "ivan@gmail.com"));
            addClient(bank, new Client(new SavingAccount(50), Client.Gender.MALE, "Ivanov B.A."));
            addClient(bank, new Client(new SavingAccount(55), Client.Gender.FEMALE, "Ivanova C.A."));
            Client client = addClient(bank, createClient(10, 5, Client.Gender.FEMALE, "Marina"));
            client.addAdditionalAccount(new SavingAccount(3));
            client.getAccounts()[0].withdraw(100);
            addClient(bank, createClient(10, 0, Client.Gender.FEMALE, "Marina"));
        } catch (NotEnoughFundsException e) {
            e.printStackTrace();
            System.out.printf("Max withdraw %f for %s\n", e.getMaxAmount(), e.getAccount());
        } catch (ClientExistsException e) {
            e.printStackTrace();
        }

        bank.setBankPath(DEFAULT_BANK_FILE_PATH);
        modifyBank(bank);
        System.out.println(print(bank, PrintType.MAX_WITHDRAW));
        return bank;
    }
}
